package com.fishery.logistics.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fishery.entity.GlobalException;
import com.fishery.entity.StatusCode;
import com.fishery.logistics.client.OrderClient;
import com.fishery.logistics.entity.Order;
import com.fishery.logistics.entity.Path;
import com.fishery.logistics.entity.Station;
import com.fishery.logistics.mapper.OrderMapper;
import com.fishery.logistics.mapper.PathMapper;
import com.fishery.logistics.mapper.StationMapper;
import com.fishery.logistics.service.PathService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author run
 * @since 2021-01-23
 */
@Service
public class PathServiceImpl extends ServiceImpl<PathMapper, Path> implements PathService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private StationMapper stationMapper;

    @Autowired
    private PathMapper pathMapper;

    @Autowired
    private OrderClient orderClient;

    @Override
    public List<Path> searchPathOfOrder(String orderId) {
        Map<String,Object> map = new HashMap<>(1,1);
        map.put("order_id",orderId);
        List<Path> pathOfOrder = pathMapper.selectByMap(map);

        Collections.sort(pathOfOrder,(p1,p2)->p1.getLogisticsPathArrivalTime().compareTo(p2.getLogisticsPathArrivalTime()));
        //将中途的站点信息封装进物流路径中
        pathOfOrder.forEach((path)->{
            path.setLogisticsPathStation(stationMapper.selectById(path.getLogisticsPathStationId()));
        });
        return pathOfOrder;
    }

    @Override
    @Transactional
    public boolean inStation(String orderId, String stationId) {
        Path path = new Path();
        Path preStation = findLatelyStation(orderId);
        if (preStation == null){
            throw new GlobalException(StatusCode.ERROR,"该站为首发站，无法执行入站操作");
        }else if (preStation.getLogisticsPathStationId().equals(stationId)) {
            throw new GlobalException(StatusCode.ERROR,"物流已到达该站，无法执行入站操作");
        }else if (preStation.getLogisticsPathDepartureTime() == null){
            throw new GlobalException(StatusCode.ERROR,"物流还未从上一个站点出发，无法执行入站操作");
        }

        Order order = orderMapper.selectById(orderId);
        if (order == null){
            throw new GlobalException(StatusCode.ERROR,"物流订单不存在！");
        }
        if (order.getLogisticsOrderStatus().equals(1)){
            throw new GlobalException(StatusCode.ERROR,"物流订单已送达");
        }
        //如果执行入站操作的站点等于目标站点，修改订单状态
        if (order.getLogisticsArrivalStationId().equals(stationId)){
            UpdateWrapper<Order> wrapper = new UpdateWrapper<>();
            wrapper.eq("id",orderId)
                    .set("logistics_order_status",1);
            int result = orderMapper.update(new Order(), wrapper);

            if (result == 0){
                throw new GlobalException(StatusCode.ERROR,"订单状态修改失败");
            }

            //同时将物流订单绑定的产品订单的状态改为送达
            orderClient.receiveOrder(orderId);
        }

        Station station = stationMapper.selectById(stationId);
        if (station == null){
            throw new GlobalException(StatusCode.ERROR,"该站点不存在，无法执行入站操作");
        }
        path.setOrderId(orderId);
        path.setLogisticsPathStationId(stationId);
        path.setLogisticsPathPreviousStationId(preStation.getLogisticsPathStationId());
        path.setLogisticsPathArrivalTime(new Date());
        return pathMapper.insert(path) > 0;
    }

    private Path findLatelyStation(String orderId){
        Page<Path> pathPage = new Page<>(1,1);
        QueryWrapper<Path> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id",orderId);
        //根据入站时间降序查找
        wrapper.orderByDesc("logistics_path_arrival_time");
        List<Path> records = pathMapper.selectPage(pathPage, wrapper).getRecords();
        return records == null ? null : records.get(0);
    }

    @Override
    public boolean outStation(String orderId, String stationId) {
        Path preStation = findLatelyStation(orderId);
        if (!preStation.getLogisticsPathStationId().equals(stationId)){
            throw new GlobalException(StatusCode.ERROR,"物流还未到达该站点，无法执行出站操作");
        }else if (preStation.getLogisticsPathDepartureTime() != null){
            throw new GlobalException(StatusCode.ERROR,"物流已驶离该站，无法执行出站操作");
        }

        Order order = orderMapper.selectById(orderId);
        if (order.getLogisticsOrderStatus().equals(1)){
            throw new GlobalException(StatusCode.ERROR,"物流已达到终点，无法执行出站操作");
        }

        Map<String,Object> map = new HashMap<>(2,1);
        map.put("order_id",orderId);
        map.put("logistics_path_station_id",stationId);
        List<Path> paths = pathMapper.selectByMap(map);

        if (paths.isEmpty()){
            return false;
        }
        Path path = paths.get(0);
        path.setLogisticsPathDepartureTime(new Date());

        return pathMapper.updateById(path) > 0;
    }
}
